#ifndef __485_SLAVE_H__
#define __485_SLAVE_H__

#include "stdint.h"
#include "stdbool.h"

typedef struct slave_reg_t
{
    uint16_t addr;
    uint16_t *data;
    uint16_t size;
    bool update;
    struct slave_reg_t *next;
    void (*reg_cb)(uint16_t *data);
} slave_reg_t;

typedef struct slave_coil_t
{
    uint16_t addr;
    uint16_t *data;
    uint16_t size;
    struct slave_coil_t *next;
} slave_coil_t;

typedef struct
{
    bool reg_update;
    uint8_t addr;
    uint32_t baudrate;
    slave_reg_t reg;   // head of reg linklist
    slave_coil_t coil; // head of coil linklist
    /* data */
} slave485_t;

extern slave485_t screen;

typedef enum
{
    SLAVE485_OK = 0x01,
    SLAVE485_ERR_INVALID_ARG = 0x02,
    SLAVE485_ERR_NO_MEM = 0x03,
    SLAVE485_ERR_REG_NOT_FOUND = 0x04,
    SLAVE485_ERR_COIL_NOT_FOUND = 0x05,
    SLAVE485_FAILED = 0x06
} slave485_err_t;

slave485_err_t slave485_init(slave485_t *slave485, uint8_t addr, uint32_t baudrate);
slave485_err_t slave485_deinit(slave485_t *slave485);
slave485_err_t slave485_analyze(slave485_t *slave485, uint8_t *data, uint16_t size);
slave485_err_t slave485_add_reg(slave485_t *slave485, slave_reg_t *reg);
slave485_err_t slave485_remove_reg(slave485_t *slave485, uint16_t addr);
slave485_err_t slave485_read_reg(slave485_t *slave485, uint16_t addr, uint16_t *data, uint16_t size);
slave485_err_t slave485_write_reg(slave485_t *slave485, uint16_t addr, uint16_t data);
slave485_err_t slave485_add_coil(slave485_t *slave485, slave_coil_t *coil);
slave485_err_t slave485_read_coil(slave485_t *slave485, uint16_t addr, uint8_t *data, uint16_t size);
slave485_err_t slave485_write_coil(slave485_t *slave485, uint16_t addr, uint16_t data);

void print_regs();

#endif